#include "EdDSA.h"

#include <ctime>

#include "data_conversion.h"

#include "../DEBUG_PRINT_MACRO.h"

#ifdef DEBUG_PRINTS_LEVEL_1
#include <iostream>
#endif

// 引入 Tracy 头文件
#include <Tracy.hpp>

// Point addition on Edwards curve
EdwardsPoint point_add(const EdwardsPoint& P, const EdwardsPoint& Q, const GMPInt& p, const GMPInt& d) {
    ZoneScopedN("EdDSA::Helper::point_add"); // 标记辅助函数
    GMPInt A, B, C, D;
    {
        ZoneScopedN("EdDSA::Helper::point_add::Calculate ABCD");
        A = (P.y - P.x) * (Q.y - Q.x) % p;
        B = (P.y + P.x) * (Q.y + Q.x) % p;
        C = 2 * P.t * Q.t * d % p;
        D = 2 * P.z * Q.z % p;
    }

    GMPInt E, F, G, H;
    {
        ZoneScopedN("EdDSA::Helper::point_add::Calculate EFGH");
        E = B - A;
        F = D - C;
        G = D + C;
        H = B + A;
    }

    GMPInt x3, y3, z3, t3;
    {
        ZoneScopedN("EdDSA::Helper::point_add::Calculate Result Coordinates");
        x3 = E * F;
        y3 = G * H;
        z3 = F * G;
        t3 = E * H;
    }

    return { x3, y3, z3, t3 };
}

// Point multiplication: Q = s * P
EdwardsPoint point_mul(const GMPInt& s, const EdwardsPoint& P, const GMPInt& p, const GMPInt& d) {
    ZoneScopedN("EdDSA::Helper::point_mul"); // 标记辅助函数
    #ifdef DEBUG_PRINTS_LEVEL_3
    gmp_printf("S:%Zd\n", s);
    #endif
    EdwardsPoint Q;
    EdwardsPoint R;
    {
        ZoneScopedN("EdDSA::Helper::point_mul::Initialization");
        Q = { mpz_class(0).get_mpz_t(), mpz_class(1).get_mpz_t(), mpz_class(1).get_mpz_t(),mpz_class(0).get_mpz_t() };  // Neutral element (0, 1)
        R = P;
    }

    GMPInt scalar = s;
    {
        ZoneScopedN("EdDSA::Helper::point_mul::Double-and-Add Loop");
        while (scalar > 0) {
            if (scalar % 2 == 1) {
                Q = point_add(Q, R, p, d); // 内部已插桩
            }
            R = point_add(R, R, p, d); // 内部已插桩
            #ifdef DEBUG_PRINTS_LEVEL_4
            // gmp_printf("Current Q: \n");
            // gmp_printf("%Zd\n", Q.x);
            // gmp_printf("%Zd\n", Q.y);
            // gmp_printf("Current R: \n");
            // gmp_printf("%Zd\n", R.x);
            // gmp_printf("%Zd\n", R.y);
            #endif
            scalar /= 2;
        }
    }

    return Q;
}

// 生成32字节的随机私钥（小端序存储）
BYTE_VECTOR generate_eddsa_secret() {
    ZoneScopedN("EdDSA::Helper::generate_eddsa_secret"); // 标记辅助函数
    gmp_randstate_t state;
    mpz_t rand_num;

    {
        ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Random State Init");
        mpz_init(rand_num);
        // 初始化随机状态（使用默认算法）
        gmp_randinit_default(state);

        // 设置随机种子（使用当前时间）
        gmp_randseed_ui(state, static_cast<unsigned long>(time(nullptr)));
    }

    try {
        {
            ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Generate Random Num");
            // 生成256位随机数（32字节）
            mpz_urandomb(rand_num, state, 256);
        }

        unsigned char buffer[32] = { 0 };
        size_t count;
        {
            ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Export to Bytes");
            // 导出为小端序字节
            mpz_export(buffer,            // 目标缓冲区
                       &count,            // 实际写入的字节数
                       -1,                // 小端序（最重要字节最后）
                       sizeof(unsigned char), // 每个字的大小
                       0,                 // 本地字节序
                       0,                 // 无符号
                       rand_num);         // 源数据

            // 补零填充（当生成的数值小于256位时）
            if (count < 32) {
                memset(buffer + count, 0, 32 - count);
            }
        }
        #ifdef DEBUG_PRINTS_LEVEL_3
        printf("[EdDSA generate secret][debug]Generate bytes: ");
        for (int i = 0;i < 32;i++) {
            printf("%02x", int(buffer[i]));
        }
        std::cout << std::endl;
        #endif    
        BYTE_VECTOR secret;
        {
            ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Convert to Vector");
            // 转换为vector
            secret = BYTE_VECTOR(buffer, buffer + 32);
        }

        {
            ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Cleanup");
            // 清理资源
            mpz_clear(rand_num);
            gmp_randclear(state);
        }

        return secret;
    }
    catch (...) {
        {
            ZoneScopedN("EdDSA::Helper::generate_eddsa_secret::Exception Cleanup");
            // 异常安全清理
            mpz_clear(rand_num);
            gmp_randclear(state);
        }
        throw;
    }
}


// 压缩Edwards点
BYTE_VECTOR point_compress(const EdwardsPoint& P, const EdwardsCurve& curve) {
    ZoneScopedN("EdDSA::Helper::point_compress"); // 标记辅助函数
    GMPInt zinv;
    {
        ZoneScopedN("EdDSA::Helper::point_compress::Calculate Z_inv");
        if (mpz_cmp_ui(P.z, 0) == 0) {
            throw std::runtime_error("Point has zero z-coordinate");
        }
        if (mpz_invert(zinv, P.z, curve.p) == 0) {
            throw std::runtime_error("Modular inverse does not exist for z-coordinate");
        }
    }

    GMPInt x_affine, y_affine;
    {
        ZoneScopedN("EdDSA::Helper::point_compress::Calculate Affine Coords");
        x_affine = (P.x * zinv) % curve.p;
        y_affine = (P.y * zinv) % curve.p;
    }

    int x_lsb;
    {
        ZoneScopedN("EdDSA::Helper::point_compress::Get X_lsb");
        x_lsb = mpz_tstbit(x_affine, 0);
    }

    GMPInt compressed_y;
    {
        ZoneScopedN("EdDSA::Helper::point_compress::Construct Compressed Y");
        compressed_y = y_affine;
        if (x_lsb) {
            if (curve.byte_length == 32) {
                mpz_setbit(compressed_y, 255); // 设置最高有效位
            }
            else if (curve.byte_length == 57) {
                mpz_setbit(compressed_y, 455); // 设置最高有效位
            }
        }
    }

    size_t byte_length = curve.byte_length; // 获取适当的字节长度
    unsigned char* compressed_bytes = new unsigned char[byte_length]();

    size_t count;
    {
        ZoneScopedN("EdDSA::Helper::point_compress::Export to Bytes");
        mpz_export(compressed_bytes, &count, -1, 1, 0, 0, compressed_y);

        if (count < byte_length) {
            memset(compressed_bytes + count, 0, byte_length - count);
        }
    }

    #ifdef DEBUG_PRINTS_LEVEL_3
    printf("[EdDSA compress][debug]Compressed bytes: ");
    for (size_t i = 0; i < byte_length; ++i) {
        printf("%02x", int(compressed_bytes[i]));
    }
    std::cout << std::endl;
    #endif

    BYTE_VECTOR result(compressed_bytes, compressed_bytes + byte_length);
    return result;
}


// 辅助函数：点相等判断
bool point_equal(const EdwardsPoint& P, const EdwardsPoint& Q, const GMPInt& p) {
    ZoneScopedN("EdDSA::Helper::point_equal"); // 标记辅助函数
    // 归一化坐标比较
    auto normalize = [&] (const EdwardsPoint& pt) -> std::pair<GMPInt, GMPInt> {
        GMPInt z_inv;
        mpz_invert(z_inv, pt.z, p);
        return { (pt.x * z_inv) % p, (pt.y * z_inv) % p };
        };

    std::pair<GMPInt, GMPInt> P_norm, Q_norm;
    {
        ZoneScopedN("EdDSA::Helper::point_equal::Normalize Points");
        P_norm = normalize(P);
        Q_norm = normalize(Q);
    }
    return (P_norm.first == Q_norm.first) && (P_norm.second == Q_norm.second);
}

struct SecretExpansion {
    mpz_class a;
    BYTE_VECTOR suffix;
};

// 辅助函数：密钥扩展
SecretExpansion secret_expand(const BYTE_VECTOR& secret, const EdwardsCurve& curve) {
    ZoneScopedN("EdDSA::Helper::secret_expand"); // 标记辅助函数
    if (secret.size() != 32) {
        throw std::runtime_error("Bad size of private key");
    }

    SHA512 hasher;
    HASH_VALUE_64 hash;
    {
        ZoneScopedN("EdDSA::Helper::secret_expand::Compute SHA512");
        // 计算SHA512哈希
        hasher.computeHash64(secret, hash);
    }

    mpz_class a;
    {
        ZoneScopedN("EdDSA::Helper::secret_expand::Convert Prefix to Integer");
        // 对于 Ed448，使用哈希值的前 28 字节 (224 位) 作为 'a'
        if (curve.byte_length == 57) { // Ed448
            mpz_import(a.get_mpz_t(), 28, -1, 1, 0, 0, hash.data());
        } else { // Ed25519
            mpz_import(a.get_mpz_t(), 32, -1, 1, 0, 0, hash.data());
        }
    }

    #ifdef DEBUG_PRINTS_LEVEL_3
    gmp_printf("[EdDSA secret expand] a1: %Zx\n", a.get_mpz_t());
    #endif

    {
        ZoneScopedN("EdDSA::Helper::secret_expand::Apply Mask and Set Bit");
        if (curve.byte_length == 32) { // Ed25519
            // 应用掩码 (1 << 254) - 8
            mpz_class mask = (mpz_class(1) << 254) - 8;
            a &= mask;
            // 设置第254位（从0开始计数为254）
            a |= (mpz_class(1) << 254);
        } else if (curve.byte_length == 57) { // Ed448
            // 清除最低两位（设置第0和第1位为0）
            mpz_clrbit(a.get_mpz_t(), 0);
            mpz_clrbit(a.get_mpz_t(), 1);
        }
    }

    BYTE_VECTOR suffix;
    {
        ZoneScopedN("EdDSA::Helper::secret_expand::Extract Suffix");
        if (curve.byte_length == 57) { // Ed448
            // 提取后 28 字节
            suffix.resize(28);
            std::copy(hash.begin() + 28, hash.begin() + 56, suffix.begin()); // 56 而不是 64
        } else { // Ed25519
            suffix.resize(32);
            std::copy(hash.begin() + 32, hash.end(), suffix.begin());
        }
    }
    return { a, suffix };
}


// 模逆计算
GMPInt modp_inv(const GMPInt& x, const GMPInt& p) {
    ZoneScopedN("EdDSA::Helper::modp_inv"); // 标记辅助函数
    GMPInt inv;
    if (mpz_invert(inv, x, p) == 0) {
        throw std::runtime_error("Modular inverse does not exist");
    }
    return inv;
}
// 点解压函数
EdwardsPoint point_decompress(const std::vector<unsigned char>& compressed, const EdDSA_publicparameter& publicParameters) {
    ZoneScopedN("EdDSA::Helper::point_decompress"); // 标记辅助函数

    // 根据曲线参数获取期望的字节长度
    int expected_length;
    if (publicParameters.curve.byte_length == 32) {
        expected_length = 32;
    }

    else if (publicParameters.curve.byte_length == 57) {
        expected_length = 57;
    }

    // 检查输入压缩点的长度是否符合预期
    if (compressed.size() != expected_length) {
        throw std::runtime_error("Invalid compressed point length");
    }

    GMPInt y;
    bool sign_bit;
    {
        ZoneScopedN("EdDSA::Helper::point_decompress::Parse Y and Sign Bit");
        // 从字节流导入y坐标
        mpz_import(y, expected_length, -1, 1, 0, 0, compressed.data());

        // 获取y坐标的最高位作为符号位
        // 注意：最高位是字节数组的最后一个字节的最高位 (第7位)
        sign_bit = (compressed[expected_length - 1] >> 7) & 1;

        // 清除y的最高位，因为这一位是符号位，不属于实际的y坐标值
        // 最高位索引是 (字节长度 * 8) - 1
        mpz_clrbit(y, expected_length * 8 - 1);
    }

    GMPInt p = publicParameters.curve.p;
    {
        ZoneScopedN("EdDSA::Helper::point_decompress::Validate Y Range");
        // 2. 验证y在素数域 p 内
        if (y >= p) {
            throw std::runtime_error("y coordinate out of range");
        }
    }

    GMPInt d = publicParameters.curve.d;
    GMPInt y_sq, x_num, x_den, x_den_inv, x_sq;
    {
        ZoneScopedN("EdDSA::Helper::point_decompress::Calculate X_sq");
        // 3. 根据Edwards曲线方程计算 x^2 = (y^2 - 1) / (d*y^2 + 1) mod p
        y_sq = (y * y) % p;
        x_num = (y_sq - 1 + p) % p; // 确保分子为正值
        x_den = (d * y_sq + 1 + p) % p; // 确保分母为正值

        // 计算分母的模逆
        x_den_inv = modp_inv(x_den, p); // 内部已插桩

        // 计算 x^2
        x_sq = (x_num * x_den_inv) % p;
    }

    GMPInt x;
    {
        ZoneScopedN("EdDSA::Helper::point_decompress::Calculate X Square Root");
        // 4. 计算x的平方根
        if (x_sq == 0) {
            // 如果 x^2 为 0，则 x 也为 0。此时符号位必须为 0。
            if (sign_bit) throw std::runtime_error("Invalid sign bit for zero x");
            x = 0;
        }
        else {
            // 根据素数 p 的模8余数选择合适的平方根计算方法
            // Ed25519 的 p ≡ 5 mod 8
            // Ed448 的 p ≡ 7 mod 8
            if ((p % 8) == 5) { // 适用于 Ed25519
                x = x_sq.powm((p + 3) / 8, p);
            }
            else if ((p % 8) == 7) { // 适用于 Ed448
                x = x_sq.powm((p + 1) / 4, p);
            }
            else {
                // 如果是其他不常见的 p mod 8 值，可能需要更通用的Tonelli-Shanks算法
                // 或者表明曲线参数不支持这种简单的平方根计算
                throw std::runtime_error("Unsupported prime modulus p for simplified square root calculation.");
            }

            // 验证计算出的 x 是否真的是 x_sq 的平方根
            GMPInt x_squared_check = (x * x) % p;
            if (x_squared_check != x_sq) {
                // 如果不是，并且曲线是 Ed25519 (p = 5 mod 8)，
                // 那么可能需要乘以 sqrt(-1) 来获得另一个正确的平方根
                if ((p % 8) == 5) { // 仅对 Ed25519 这种 p = 5 mod 8 的情况有效
                    // Ed25519 的 sqrt(-1) 是一个固定常数
                    const GMPInt sqrt_m1_ed25519(mpz_class("19681161376707505956807079304988542015446066515923890162744021073123829784752").get_mpz_t());
                    x = (x * sqrt_m1_ed25519) % p;
                    if ((x * x) % p != x_sq) {
                        throw std::runtime_error("Cannot recover x coordinate (even after multiplying by sqrt(-1))");
                    }
                }
                else {
                    // 对于 Ed448 (p = 7 mod 8)，如果到这里 x^2 仍然不等于 x_sq，
                    // 说明 x_sq 根本不是二次剩余，这是一个无效的压缩点。
                    throw std::runtime_error("Cannot recover x coordinate - x_sq is not a quadratic residue.");
                }
            }

            // 检查并调整 x 的最低位以匹配符号位
            if ((x % 2) != sign_bit) {
                x = p - x; // 取另一个符号相反的根
            }
        }
    }

    {
        ZoneScopedN("EdDSA::Helper::point_decompress::Construct EdwardsPoint");
        // 5. 返回扩展坐标 (X, Y, Z, T) = (x, y, 1, x*y mod p)
        return EdwardsPoint{ x, y, GMPInt(1), (x * y) % p };
    }
}

EdwardsCurve get_Ed25519() {
    ZoneScopedN("EdDSA::CurveParams::get_Ed25519"); // 标记曲线参数获取函数
    // 定义ED25519曲线的参数

    mpz_t p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt;
    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed25519::Initialization");
        mpz_inits(p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt, nullptr);

        mpz_set_str(p_mpzt, "57896044618658097711785492504343953926634992332820282019728792003956564819949", 10);
        mpz_set_str(n_mpzt, "7237005577332262213973186563042994240857116359379907606001950938285454250989", 10);
        mpz_set_str(d_mpzt, "37095705934669439343138083508754565189542113879843219016388785533085940283555", 10);
        mpz_set_str(g_x_mpzt, "15112221349535400772501151409588531511454012693041857206046113283949847762202", 10);
        mpz_set_str(g_y_mpzt, "46316835694926478169428394003475163141307993866256225615783033603165251855960", 10);
    }

    GMPInt p(p_mpzt);  // 素数域模数
    GMPInt d(d_mpzt);  // 曲线参数
    GMPInt n(n_mpzt);  // 基点的阶

    GMPInt g_y(g_y_mpzt);
    GMPInt g_x(g_x_mpzt);
    GMPInt g_z;
    EdwardsPoint G;
    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed25519::Construct Base Point");
        g_z = g_x * g_y % p;
        G = { g_x, g_y, mpz_class(1).get_mpz_t(), g_z };  // 构造基点 (x, y, 1, z)
    }

    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed25519::Cleanup");
        mpz_clears(p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt, nullptr);
    }

    return EdwardsCurve(d, p, G, n, 32);
}

EdwardsCurve get_Ed448() {
    ZoneScopedN("EdDSA::CurveParams::get_Ed448"); // 标记曲线参数获取函数
    mpz_t p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt;
    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed448::Initialization");
        mpz_inits(p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt, nullptr);

        mpz_set_str(p_mpzt, "fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16);
        mpz_set_str(n_mpzt, "3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3", 16);
        mpz_set_str(d_mpzt, "d78b4bdc7f0daf19f24f38c29373a2ccad46157242a50f37809b1da3412a12e79ccc9c81264cfe9ad080997058fb61c4243cc32dbaa156b9", 16);
        mpz_set_str(g_x_mpzt, "79a70b2b70400553ae7c9df416c792c61128751ac92969240c25a07d728bdc93e21f7787ed6972249de732f38496cd11698713093e9c04fc", 16);
        mpz_set_str(g_y_mpzt, "7fffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000001", 16);
    }

    GMPInt p(p_mpzt);  // 素数域模数
    GMPInt d(d_mpzt);  // 曲线参数
    GMPInt n(n_mpzt);  // 基点的阶

    GMPInt g_y(g_y_mpzt);
    GMPInt g_x(g_x_mpzt);
    GMPInt g_z;
    EdwardsPoint G;
    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed448::Construct Base Point");
        g_z = g_x * g_y % p;
        G = { g_x, g_y, mpz_class(1).get_mpz_t(), g_z };
    }

    {
        ZoneScopedN("EdDSA::CurveParams::get_Ed448::Cleanup");
        mpz_clears(p_mpzt, d_mpzt, n_mpzt, g_y_mpzt, g_x_mpzt, nullptr);
    }

    return EdwardsCurve(d, p, G, n, 57);
}


template<typename curve_name>
void EdDSA<curve_name>::generatepublicparameters(EdDSA_publicparameter& publicParameters) {
    ZoneScopedN("EdDSA::generatepublicparameters"); // 标记整个函数
    // 将参数存储在公共参数结构中
    {
        ZoneScopedN("EdDSA::generatepublicparameters::Load Curve");
        // 根据 curve_name 使用 if constexpr 根据模板参数选择曲线
        if constexpr (std::is_same_v<curve_name, Ed25519_tag>) {
            ZoneScopedN("ECDSA::generatepublicparameters::Load Ed25519");
            // 选择 Ed25519 曲线
            publicParameters = EdDSA_publicparameter(get_Ed25519());
            publicParameters.is_valid = true;
            std::cout << "Using Ed25519 curve parameters." << std::endl;
        }
        else if constexpr (std::is_same_v<curve_name, Ed448_tag>) {
            ZoneScopedN("ECDSA::generatepublicparameters::Load Ed448");
            // 选择 Ed448 曲线
            publicParameters = EdDSA_publicparameter(get_Ed448());
            publicParameters.is_valid = true;
            std::cout << "Using Ed448 curve parameters." << std::endl;
        }
        publicParameters = EdDSA_publicparameter(get_Ed25519());
        publicParameters.is_valid = true;
    }
}

template<typename curve_name>
void EdDSA<curve_name>::generateKeyPair(
    EdDSA_privatekey& privateKey,
    EdDSA_publickey& publicKey,
    EdDSA_publicparameter& publicParameters
) {
    ZoneScopedN("EdDSA::generateKeyPair"); // 标记整个函数
    {
        ZoneScopedN("EdDSA::generateKeyPair::Parameter Validation");
        if (!publicParameters.is_valid) {
            generatepublicparameters(publicParameters); // 内部已插桩
        }
    }

    BYTE_VECTOR s;
    SecretExpansion s_expend;
    {
        ZoneScopedN("EdDSA::generateKeyPair::Secret Key Generation and Expansion");
        // --------------------------
        // 1. 随机生成一个32字节的私钥s
        // --------------------------
        s = generate_eddsa_secret(); // 内部已插桩

        // 对s进行密钥扩展
        s_expend = secret_expand(s, publicParameters.curve); // 内部已插桩
    }

    privateKey.s = s;
    #ifdef DEBUG_PRINTS_LEVEL_3
    gmp_printf("[EdDSA KeyPair]S: %Zd\n", s_expend.a.get_mpz_t());
    #endif

    EdwardsPoint A;
    {
        ZoneScopedN("EdDSA::generateKeyPair::Calculate Public Key A");
        // ----------------------------
        // 2. 计算公钥 A = s_expend * G
        // ----------------------------
        A = point_mul(GMPInt(s_expend.a.get_mpz_t()), publicParameters.curve.G, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
    }

    {
        ZoneScopedN("EdDSA::generateKeyPair::Compress Public Key");
        // 压缩成32字节，设置为公钥
        publicKey.a = point_compress(A, publicParameters.curve); // 内部已插桩
        printf("[EdDSA KeyPair][debug]Public Key A compressed successfully.\n");
    }
}


// 辅助函数：SHA512哈希后模q
GMPInt sha512_modq(const BYTE_VECTOR& data, const GMPInt& q) {
    ZoneScopedN("EdDSA::Helper::sha512_modq"); // 标记辅助函数
    SHA512 hasher;
    HASH_VALUE_64 hash;
    {
        ZoneScopedN("EdDSA::Helper::sha512_modq::Compute Hash");
        hasher.computeHash64(data, hash);
    }

    GMPInt result;
    {
        ZoneScopedN("EdDSA::Helper::sha512_modq::Convert to GMP and Modulo");
        mpz_import(result, 64, -1, 1, 0, 0, hash.data());
        return result % q;
    }
}

// 签名消息：使用私钥s和参数生成签名(R, S)
template<typename curve_name>
EdDSA_signature EdDSA<curve_name>::sign(
    const PlainMessage& message,
    const EdDSA_privatekey& privateKey,
    const EdDSA_publicparameter& publicParameters
) {
    ZoneScopedN("EdDSA::sign"); // 标记整个函数

    {
        ZoneScopedN("EdDSA::sign::Parameter Validation");
        // 验证公共参数有效性
        if (!publicParameters.is_valid) {
            throw std::invalid_argument("Invalid EdDSA public parameters");
        }
    }

    SecretExpansion se;
    GMPInt a;
    BYTE_VECTOR prefix;
    BYTE_VECTOR A_compressed;
    {
        ZoneScopedN("EdDSA::sign::Key Expansion and Public Key Compression");
        // ----------
        // 1. 密钥扩展
        // ----------
        se = secret_expand(privateKey.s, publicParameters.curve); // 内部已插桩
        a = GMPInt{ se.a.get_mpz_t() };
        prefix = se.suffix;
        EdwardsPoint A_point = point_mul(a, publicParameters.curve.G, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
        A_compressed = point_compress(A_point, publicParameters.curve); // 内部已插桩
    }

    GMPInt r;
    {
        ZoneScopedN("EdDSA::sign::Calculate R_scalar");
        // --------------------
        // 2. 计算r = H(前缀, m)
        // --------------------
        BYTE_VECTOR r_input(prefix);
        r_input.insert(r_input.end(), message.get_data_begin(), message.get_data_end());
        r = sha512_modq(r_input, publicParameters.curve.n); // 内部已插桩
    }

    EdwardsPoint R_point;
    {
        ZoneScopedN("EdDSA::sign::Calculate R_point");
        // ----------------
        // 3. 计算R = r * G
        // ----------------
        R_point = point_mul(r, publicParameters.curve.G, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
    }

    GMPInt h;
    {
        ZoneScopedN("EdDSA::sign::Calculate H_scalar");
        // --------------------------
        // 4. 计算h = H(R, A, message)
        // --------------------------
        BYTE_VECTOR Rs_compressed = point_compress(R_point, publicParameters.curve); // 内部已插桩
        BYTE_VECTOR h_input(Rs_compressed);
        h_input.insert(h_input.end(), A_compressed.begin(), A_compressed.end());
        h_input.insert(h_input.end(), message.get_data_begin(), message.get_data_end());
        h = sha512_modq(h_input, publicParameters.curve.n); // 内部已插桩
    }

    GMPInt s_signature;
    {
        ZoneScopedN("EdDSA::sign::Calculate S_signature");
        // -------------------------------
        // 5. 计算s = (r + h·s_priv) mod n
        // -------------------------------
        s_signature = (r + h * a) % publicParameters.curve.n;
    }

    return EdDSA_signature(R_point, s_signature);
}


// 验证签名：检查R + S*A 是否与消息哈希对应的点匹配
template<typename curve_name>
bool EdDSA<curve_name>::verify(
    const PlainMessage& message,
    const EdDSA_publickey& publicKey,
    const EdDSA_publicparameter& publicParameters,
    const EdDSA_signature& signature
) {
    ZoneScopedN("EdDSA::verify"); // 标记整个函数

    {
        ZoneScopedN("EdDSA::verify::Parameter Validation");
        // 验证公共参数有效性
        if (!publicParameters.is_valid) {
            throw std::invalid_argument("Invalid EdDSA public parameters");
        }
    }

    try {
        {
            ZoneScopedN("EdDSA::verify::Public Key Length Check");
            // ------------
            // 1. 参数校验
            // -------------
            if (publicKey.a.size() != publicParameters.curve.byte_length) {
                throw std::runtime_error("Invalid public key length");
            }
        }

        EdwardsPoint A_decompressed;
        {
            ZoneScopedN("EdDSA::verify::Decompress Public Key A");
            // ------------
            // 2. 解压公钥A
            // -------------
            A_decompressed = point_decompress(publicKey.a, publicParameters); // 内部已插桩
        }

        BYTE_VECTOR Rs_compressed;
        {
            ZoneScopedN("EdDSA::verify::Compress R Point");
            // ------------
            // 3. 压缩R点
            // -------------
            Rs_compressed = point_compress(signature.R, publicParameters.curve); // 内部已插桩
        }

        {
            ZoneScopedN("EdDSA::verify::S Range Check");
            // ------------------
            // 4. 验证s范围: s < n
            // ------------------
            if (signature.S >= publicParameters.curve.n) {
                return false;
            }
        }

        GMPInt h;
        {
            ZoneScopedN("EdDSA::verify::Calculate H_scalar");
            // ---------------------------
            // 5. 计算h = H(R, A, message)
            // ---------------------------
            BYTE_VECTOR h_input(Rs_compressed);
            h_input.insert(h_input.end(), publicKey.a.begin(), publicKey.a.end());
            h_input.insert(h_input.end(), message.get_data_begin(), message.get_data_end());
            h = sha512_modq(h_input, publicParameters.curve.n); // 内部已插桩
        }

        EdwardsPoint sB, hA, R_plus_hA;
        {
            ZoneScopedN("EdDSA::verify::Calculate sB and hA");
            // ---------------------------------------------
            // 6. 计算各点:sB = s * B, R_plus_hA = R + h * A
            // ---------------------------------------------
            sB = point_mul(signature.S, publicParameters.curve.G, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
            hA = point_mul(h, A_decompressed, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
        }
        {
            ZoneScopedN("EdDSA::verify::Add R and hA");
            R_plus_hA = point_add(signature.R, hA, publicParameters.curve.p, publicParameters.curve.d); // 内部已插桩
        }

        {
            ZoneScopedN("EdDSA::verify::Compare Points");
            // -----------------------------
            // 7. 验证点sB与R_plus_hA是否相等
            // -----------------------------
            return point_equal(sB, R_plus_hA, publicParameters.curve.p); // 内部已插桩
        }
    }
    catch (const std::exception& e) {
        ZoneScopedN("EdDSA::verify::Exception Handling"); // 标记异常捕获区域
        std::cerr << "Verification error: " << e.what() << std::endl;
        return false;
    }
}

template class EdDSA<Ed25519_tag>;
template class EdDSA<Ed448_tag>;